#include "syncworker.h"
#include <QNetworkRequest>
#include <QJsonDocument>
#include <QJsonObject>
#include <QSqlQuery>
#include <QDebug>
#include <QFile>
#include <QUrl>
#include <QNetworkReply>  // 缺失的头文件
#include <QJsonArray>  // 缺失的头文件
#include <QSqlError>  // 缺失的头文件
#include <QUrlQuery>

SyncWorker::SyncWorker(QObject *parent) : QObject(parent) {
    m_nam = new QNetworkAccessManager(this);

    // 确保信号槽正确连接
    connect(m_nam, &QNetworkAccessManager::finished, this, &SyncWorker::onReplyFinished);

    // 初始化数据库
    m_db = QSqlDatabase::addDatabase("QSQLITE");
    m_db.setDatabaseName("/root/database/memoryGame.db");

    if (!m_db.open()) {
        qCritical() << "db open fail:" << m_db.lastError().text();
        return;
    }
}

void SyncWorker::startSync() {
    QString lastSyncFile = "/tmp/last_cloud_sync_time";
    QString lastSync = "2023-01-01 00:00:00";

    // 读取上次同步时间
    QFile file(lastSyncFile);
    if (file.exists() && file.open(QIODevice::ReadOnly)) {
        QTextStream in(&file);
        lastSync = in.readAll().trimmed();
        file.close();
    }

    // 替换 T 为空格并截断毫秒
    lastSync = lastSync.replace("T", " ").split(".").first();

    // 检查 since 时间是否大于当前时间
    QDateTime sinceTime = QDateTime::fromString(lastSync, "yyyy-MM-dd HH:mm:ss");
    sinceTime = sinceTime.toUTC(); // 强制转换为 UTC
    lastSync = sinceTime.toString("yyyy-MM-dd HH:mm:ss");
    QDateTime now = QDateTime::currentDateTime();
    if (sinceTime > now) {
        qWarning() << "since 时间大于当前时间，重置为当前时间";
        lastSync = now.toString("yyyy-MM-dd HH:mm:ss");
    }

    // 使用QUrl自动处理URL编码
    QUrl url("http://47.109.75.129:3000/reminders");
    QUrlQuery query;
    query.addQueryItem("since", lastSync);
    url.setQuery(query.query());

    qDebug() << "request net update" << url.toString();

    QNetworkRequest request(url);
    m_nam->get(request);
}

void SyncWorker::onReplyFinished(QNetworkReply *reply) {
    if (reply->error() != QNetworkReply::NoError) {
        qCritical() << "request fail" << reply->errorString();
        reply->deleteLater();
        return;
    }

    QByteArray data = reply->readAll();
    reply->deleteLater(); // 及时释放资源

    QJsonParseError error;
    QJsonDocument doc = QJsonDocument::fromJson(data, &error);

    if (error.error != QJsonParseError::NoError) {
        qCritical() << "JSON analyze fail" << error.errorString();
        return;
    }

    if (!doc.isArray()) {
        qDebug() << "no new data,get out sync";
        return;
    }

    QJsonArray array = doc.array();
    QSqlQuery query(m_db);

    foreach (const QJsonValue &value, array) {
        if (!value.isObject()) continue;
        QJsonObject obj = value.toObject();

        // 显式检查字段是否存在
        if (!obj.contains("id") || !obj.contains("content")) {
            qWarning() << "lack id && content ,skip updating";
            continue;
        }

        int id = obj["id"].toInt();
        QString content = obj["content"].toString();
        QString triggerTime = obj["triggerTime"].toString();
        QString repeat = obj["repeat"].toString();
        int isCompleted = obj["isCompleted"].toInt(0);

        if (content.isEmpty()) {
            qWarning() << "info is empty, ID:" << id;
            continue;
        }

        // 替换 T 为空格并截断毫秒
        triggerTime = triggerTime.replace("T", " ").split(".").first();

        // 检查本地是否存在该 id 的记录
        QSqlQuery checkQuery(m_db);
        checkQuery.prepare("SELECT content, triggerTime, repeat, isCompleted FROM Reminder WHERE id = ?");
        checkQuery.addBindValue(id);
        if (!checkQuery.exec()) {
            qCritical() << "SQL check fail" << checkQuery.lastError().text();
            continue;
        }

        bool exists = checkQuery.next();

        // 如果存在，比较字段
        if (exists) {
            QString localContent = checkQuery.value(0).toString();
            QString localTriggerTime = checkQuery.value(1).toString();
            QString localRepeat = checkQuery.value(2).toString();
            int localIsCompleted = checkQuery.value(3).toInt();

            if (content == localContent &&
                triggerTime == localTriggerTime &&
                repeat == localRepeat &&
                isCompleted == localIsCompleted) {
                // 内容一致，跳过更新
                continue;
            } else {
                // 内容不同，执行更新
                QString updateSql = "UPDATE Reminder SET content = ?, triggerTime = ?, repeat = ?, isCompleted = ? WHERE id = ?";
                if (!query.prepare(updateSql)) {
                    qCritical() << "SQL prepare fail" << query.lastError().text();
                    continue;
                }
                query.addBindValue(content);
                query.addBindValue(triggerTime);
                query.addBindValue(repeat);
                query.addBindValue(isCompleted);
                query.addBindValue(id);
                if (!query.exec()) {
                    qCritical() << "SQL update fail" << query.lastError().text();
                    qCritical() << "fail SQL" << query.executedQuery();
                }
            }
        } else {
            // 不存在该 id，执行插入
            QString insertSql = "INSERT INTO Reminder (id, content, triggerTime, repeat, isCompleted) VALUES (?, ?, ?, ?, ?)";
            if (!query.prepare(insertSql)) {
                qCritical() << "SQL prepare fail" << query.lastError().text();
                continue;
            }
            query.addBindValue(id);
            query.addBindValue(content);
            query.addBindValue(triggerTime);
            query.addBindValue(repeat);
            query.addBindValue(isCompleted);
            if (!query.exec()) {
                qCritical() << "SQL insert fail" << query.lastError().text();
                qCritical() << "fail SQL" << query.executedQuery();
            }
        }
    }

    // 更新最后同步时间（保持不变）
    if (!array.isEmpty()) {
        QJsonObject latest = array.last().toObject();
        QString newestTime = latest["triggerTime"].toString();

        // 替换 T 为空格并截断毫秒
        newestTime = newestTime.replace("T", " ").split(".").first();

        // 将字符串时间转换为 QDateTime 对象
        QDateTime newTime = QDateTime::fromString(newestTime, "yyyy-MM-dd HH:mm:ss");
        newTime = newTime.toLocalTime(); // 转换为本地时间存储
        newestTime = newTime.toString("yyyy-MM-dd HH:mm:ss");
        QDateTime now = QDateTime::currentDateTime();  // 获取当前系统时间

        if (!newestTime.isEmpty()) {
            QFile file("/tmp/last_cloud_sync_time");
            if (file.open(QIODevice::WriteOnly | QIODevice::Truncate)) {
                QTextStream out(&file);
                out << newestTime;
                file.close();
                qDebug() << "last sync time:" << newestTime;
            } else {
                qWarning() << "can't write last sync time";
            }
        }
    }

    qDebug() << "sync succ";
}
